/***************************************************
> Copyright (C) 2024 ==QWZL== All rights reserved.
> File Name: WPH_server.c
> Author:nxq
> Mail:nxq949698473@163.com 
> Created Time: 2024年07月23日 星期二 20时00分16秒
***************************************************/

#include "WPH_server.h"

void producer()
{
    threadPool *pool = NULL;
	pool = create_threadPool(5,10); //创建线程池，初始化

    int sock = 0;
    int ret = 0;
    char buf[1024] = {0};
    int listen_sock = 0;

    listen_sock = linstenSock();

    while(1)
    {
        sock = accept(listen_sock,NULL,NULL);
        if(sock == -1)
        {
            perror("accept");
            exit(-1);
        }

        sem_wait(&pool->semw);
 		pthread_mutex_lock(&pool->mutex); 

        push(sock,pool->queue);//sock入队

        sem_post(&pool->semr);
 		pthread_mutex_unlock(&pool->mutex);
    }

    close(listen_sock);
    destroy_threadPool(pool);
}

//获取监听套接字
int linstenSock()
{
    int ret = 0;
    int listen_sock = 0;
	struct sockaddr_in addr;
	memset(&addr,0,sizeof(addr));

	listen_sock = socket(AF_INET,SOCK_STREAM,0);
	if(listen_sock == -1)
	{
		perror("socket");
		exit(-1);
	}

	addr.sin_family = AF_INET;
	addr.sin_port = htons(6666);
	addr.sin_addr.s_addr = inet_addr("192.168.0.185");

	ret = bind(listen_sock,(struct sockaddr *)&addr,sizeof(struct sockaddr));
	if(ret == -1)
	{
		perror("bind");
		exit(-1);
	}

	ret = listen(listen_sock,5);
	if(ret == -1)
	{
		perror("listen");
	}

    return listen_sock;
}

void *consumer(void *arg)
{
    threadPool *pool = ( threadPool *)arg;

    char buf[100] = {0};
	int ret = 0;
    int sock = 0;

    int value = 0;
    struct regulator info;
    memset(&info,0,sizeof(info));
    struct staff staff_info;
    memset(&staff_info,0,sizeof(staff_info));

	while(1)
	{
		sem_wait(&pool->semr);

		pthread_mutex_lock(&pool->mutex);//上锁

		sock = front(pool->queue);//获取第一个节点元素

		pop(pool->queue);//出队

		sem_post(&pool->semw);
		pthread_mutex_unlock(&pool->mutex);//解锁

        while(1) 
        {
            ret = recv(sock,buf,sizeof(buf),0);
            if(ret == -1)
            {
                perror("recv");
                exit(-1);
            }

            puts(buf);

            if(info.id == 1)
            {
                unpack(buf);//注册管理员账号信息解包
                fun(info);
            }    
            
            if(staff_info.Uid > 1)
            {
                staffInfo(buf);//注册员工账号信息解包
                fun2(staff_info);
            }
            
            
        }
	}
    close(sock);
}

//注册管理员信息解包
struct regulator unpack(char *buf)
{
    struct regulator info;
    memset(&info,0,sizeof(info));

    //定义cJSON指针
    cJSON *json = NULL;
    //将字符串转为json格式对象
    json = cJSON_Parse(buf);

    cJSON *node = NULL;
    //由键获取值
    node = cJSON_GetObjectItem(json,"id");
    if(node == NULL)
    {
        printf("can't find\n");
        exit(-1);
    }
    if(node->type == cJSON_Number)
    {
        info.id = node->valueint;
    }

    node = cJSON_GetObjectItem(json,"name");
    if(node == NULL)
    {
        printf("can't find\n");
        exit(-1);
    }
    if(node->type == cJSON_String)
    {
        strcpy(info.name,node->valuestring);
    }

    node = cJSON_GetObjectItem(json,"gender");
    if(node == NULL)
    {
        printf("can't find\n");
        exit(-1);
    }
    if(node->type == cJSON_String)
    {
        strcpy(info.gender,node->valuestring);
    }

    node = cJSON_GetObjectItem(json,"age");
    if(node == NULL)
    {
        printf("can't find\n");
        exit(-1);
    }
    if(node->type == cJSON_Number)
    {
        info.age = node->valueint;
    }

    node = cJSON_GetObjectItem(json,"account");
    if(node == NULL)
    {
        printf("can't find\n");
        exit(-1);
    }
    if(node->type == cJSON_Number)
    {
        info.account = node->valueint;
    }

    node = cJSON_GetObjectItem(json,"cipher");
    if(node == NULL)
    {
        printf("can't find\n");
        exit(-1);
    }
    if(node->type == cJSON_Number)
    {
        info.cipher = node->valueint;
    }
    cJSON_Delete(json);	
    return info;
}

//注册员工信息解包
struct staff staffInfo(char *buf)
{
    struct staff staff_info;
    memset(&staff_info,0,sizeof(staff_info));

    //定义cJSON指针
    cJSON *json = NULL;
    //将字符串转为json格式对象
    json = cJSON_Parse(buf);

    cJSON *node = NULL;
    //由键获取值
    node = cJSON_GetObjectItem(json,"Uid");
    if(node == NULL)
    {
        printf("can't find\n");
        exit(-1);
    }
    if(node->type == cJSON_Number)
    {
        info.id = node->valueint;
    }

    node = cJSON_GetObjectItem(json,"name");
    if(node == NULL)
    {
        printf("can't find\n");
        exit(-1);
    }
    if(node->type == cJSON_String)
    {
        strcpy(staff_info.name,node->valuestring);
    }

    node = cJSON_GetObjectItem(json,"gender");
    if(node == NULL)
    {
        printf("can't find\n");
        exit(-1);
    }
    if(node->type == cJSON_String)
    {
        strcpy(staff_info.gender,node->valuestring);
    }

    node = cJSON_GetObjectItem(json,"age");
    if(node == NULL)
    {
        printf("can't find\n");
        exit(-1);
    }
    if(node->type == cJSON_Number)
    {
        staff_info.age = node->valueint;
    }

    node = cJSON_GetObjectItem(json,"account");
    if(node == NULL)
    {
        printf("can't find\n");
        exit(-1);
    }
    if(node->type == cJSON_Number)
    {
        staff_info.account = node->valueint;
    }

    node = cJSON_GetObjectItem(json,"cipher");
    if(node == NULL)
    {
        printf("can't find\n");
        exit(-1);
    }
    if(node->type == cJSON_Number)
    {
        staff_info.cipher = node->valueint;
    }
    cJSON_Delete(json);	
    return staff_info;
}

//功能
void fun(struct regulator *info)
{
    int value = 0;

    if(info.id == 1)
    {        
        value = 1;//成功
    }
    else
    {
        value = 0;//失败
    }
    ret = send(sock,&value,4,0);
    if(ret == -1)
    {
        perror("sendto");
        exit(-1);
    }
}

//功能
void fun2(struct staff *staff_info)
{
    int value1 = 0;

    if(staff_info.Uid > 1)
    {        
        value1 = 1;//成功
    }
    else
    {
        value1 = 0;//失败
    }
    ret = send(sock,&value1,4,0);
    if(ret == -1)
    {
        perror("sendto");
        exit(-1);
    }
}